# Merise python parser and models generators.
#
# @autor: Patrice Ferlet <metal3d@gmail.com>
# @version 0.0.2
# @licence Gnu/GPL v3

# $Id: sqlite.py 52 2010-08-02 16:08:20Z Metal3d $
# $HeadURL: http://merisier.googlecode.com/svn/tags/0.0.2-alpha3/src/merise/backend/sqlite.py $

import sys,re,os
from datetime import date,time,datetime

class Generator:
	def __init__(self,parser):
		self.parser = parser
		(self.basename, ext) = os.path.splitext(os.path.basename(self.parser.options.filename))
				
	def generate(self):
		"""
		Generate SQL file
		"""
		sql = "";
		drops = []
		for k,v in self.parser.defs.items():
			drops.append("DROP TABLE IF EXISTS %s;" % k)
			template = "CREATE TABLE %s (\n%s\n);"
			fielddef = []
			primary = []
			fkfield = []
			for field in v:
				if len(field) == 0:
					continue
				#field has "+" symbole, it's a key
				if re.search('\+',field):
					field = field.replace('+','')
					try:
						#if type is defined we check if it's an auto increment field
						if len(self.parser.types[k]):
							for _fielddef in self.parser.types[k]:
								if _fielddef[0] == field:
									if len(_fielddef[1])>0 and _fielddef[1]!='auto':
										_type = _fielddef[1]
									else:
										_type = "INTEGER PRIMARY KEY"

								#check null value	 
								if _fielddef[2] and _fielddef[4] is not None and not _fielddef[4]:
									fkfield.append((_fielddef[0],_fielddef[3]))

					except:
						_type = "INTEGER PRIMARY KEY"

					done = []
					fklines = []
					for fkf,ref in fkfield:
						for kk in self.parser.keys[ref]:
							if kk not in done:
								fklines.append('\tFOREIGN KEY (%s) REFERENCES %s(%s) ON DELETE CASCADE' % (fkf, ref, kk))
								done.append(kk)
												   
					fielddef.append("\t%s %s" % (field, _type))
					

				#it's not a key, check definition
				else:
					_type = "varchar(255) not null"
					#find type...
					try:
						if len(self.parser.types[k]):
							for _fielddef in self.parser.types[k]:
								if _fielddef[0] == field:
									if len(_fielddef[1]):
										_type = _fielddef[1]
									else:
										_type = "varchar(255)"

									# field is foreign key 
									if _fielddef[2]==True:
										if _type=="auto":
											_type = 'int(11)'
										if _fielddef[4] is not None and not _fielddef[4]: 
											fkfield.append((_fielddef[0],_fielddef[3]))
							if _fielddef[4] is not None and not re.search(r'null',_type):
								if not _fielddef[4]:
									_type+=' not null'

					except:
						_type = "varchar(255) not null"
					
					fklines = []
					done = []
					for fkf,ref in fkfield:
						if fkf not in done:
							for kk in self.parser.keys[ref]:
								if kk not in done:
									fklines.append('\tFOREIGN KEY (%s) REFERENCES %s(%s) ON DELETE CASCADE' % (fkf, ref, kk))
								done.append(kk)
						done.append(fkf)
				 
					fielddef.append("\t%s %s" % (field, _type))
			
			if len(fklines):
				fielddef.append(",\n".join(fklines))
					
			if len(primary):
				fielddef.append("\tPRIMARY KEY(%s)" % ",".join(primary) )

			fielddef = ",\n".join(fielddef);
			sql+= template % (str(k) , fielddef) + "\n\n"

		#it could be fine to know when SQL ha been generated		
		d = datetime.now()

		sql = "PRAGMA foreign_keys=OFF;\n\n%s\n\n%s\nPRAGMA foreign_keys=ON;" % ("\n".join(drops) , sql)
		sql = "/*Generated with %s - %s */\n" % (sys.argv[0], d.strftime("%A, %d. %B %Y %H:%M")) + sql
		
		path=os.path.join( self.parser.options.directory, self.basename+"_sqlite.sql" )
		
		f= open(path,"w")
		f.write(sql)
		f.close()
		
		print path+" generated"
